#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MN = 4e5 + 1;

#define rep(i, a, b) for (int(i) = a; (i) <= b; (i)++)

int father[MN];
// int rank[MN];
LL x[MN]; // 记录 i节点相对于父节点的x位置
LL y[MN]; // 记录 i节点相对于父节点的y位置

void init(int n) {
  for (int i = 1; i <= n; i++) {
    father[i] = i;
    // rank[i] = 0;
    x[i] = 0;
    y[i] = 0;
  }
}
// 找k节点所在的树的根
int find(int k) {
  if (father[k] == k)
    return k;
  int root = find(father[k]);
  x[k] += x[father[k]];
  y[k] += y[father[k]];
  return father[k] = root; // 路径压缩
}

void unite(char d, int a, int b, int e) {
  int ra = find(a);
  int rb = find(b);
  if (ra == rb)
    return;
  father[ra] = rb;

  switch (d) {
  case 'N':
    y[ra] = -y[a] + e + y[b];
    x[ra] = -x[a] + x[b];  
    break;
  case 'S':
    y[ra] = -y[a] - e + y[b];
    x[ra] = -x[a] + x[b];
    break;
  case 'W':
    x[ra] = -x[a] - e + x[b];
    y[ra] = -y[a] + y[b];
    break;
  case 'E':
    x[ra] = -x[a] + e + x[b]; // ra相对于rb:  -x[a]+e+x[b]
    y[ra] = -y[a] + y[b];
    break;
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  init(n);
  for (int i = 1; i <= m; i++) {
    char ch;
    cin >> ch;
    if (ch == '?') {
      int a, b;
      cin >> a >> b;
      if (find(a) != find(b)) {
        cout << "?" << endl;
      } else {
        cout << abs(x[a] - x[b]) + abs(y[a] - y[b]) << endl;
      }
    } else {
      int a, b, e;
      cin >> a >> b >> e;
      unite(ch, a, b, e);
      // rep(i, 1, n) {
      //   cout << i << " " << father[i] << " " << x[i] << " " << y[i] << endl;
      // }
    }
  }

  return 0;
}